import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * @author 3489309323@qq.com
 * @create 2020-09-14-21:53
 *
 * CompletableFuture提供了四个静态方法来创建一个异步操作(两个方法名 每个方法名有两个不同重载方法)
 */
public class P1CompletableFutureTest {
  public static ExecutorService executor = Executors.newFixedThreadPool(10);

  public static void main(String[] args) throws ExecutionException, InterruptedException {
    System.out.println("main...start...");

    /** 选择一: CompletableFuture.runAsync */
    /*CompletableFuture<Void> voidCompletableFuture = CompletableFuture.runAsync(() -> {
      System.out.println("当前线程id: " + Thread.currentThread().getId());
      int i = 10 / 2;
      System.out.println("运行结果: " + i);
    }, executor);

    System.out.println("main...end...");*/
//main...start...
//main...end...
//当前线程id: 20
//运行结果: 5

    /** 选择二: CompletableFuture.supplyAsync 相较于方式一,有返回值,并且会阻塞当前线程*/
   /* CompletableFuture<Integer> integerCompletableFuture = CompletableFuture.supplyAsync(() -> {
      System.out.println("当前线程id: " + Thread.currentThread().getId());
      int i = 10 / 2;
      System.out.println("运行结果: " + i);
      return i;
    }, executor).whenCompleteAsync((res,err)->{
      System.out.println("异步任务成功完成了 ... 结果是: "+res+";异常是:"+err);
    });

    System.out.println("异步方法的返回值是:"+integerCompletableFuture.get()); //异步方法的返回值是:5
    System.out.println("main...end...");*/
//main...start...
//当前线程id: 20
//运行结果: 5
//异步方法的返回值是:5
//main...end...



    /** 完成回调与异常感知
     * .whenComplete、whenCompleteAsync
     * .exceptionally
     * */
    /*CompletableFuture<Integer> integerCompletableFuture = CompletableFuture.supplyAsync(() -> {
      System.out.println("当前线程id: " + Thread.currentThread().getId());
      //int i = 10 / 2;
      int i = 10 / 0;
      System.out.println("运行结果: " + i);
      return i;
    }, executor).whenComplete((res,err)->{
      //whenComplete与上一个线程用同一个线程
      //whenCompleteAsync会任务交给线程池(So也有几率是交给同一个线程执行)
      System.out.println("异步任务成功完成了 ... 结果是: "+res+";异常是:"+err);
    }).exceptionally(err -> {
      //todo whenComplete虽然也能得到异常信息, 但是没法修改返回数据
      //  而exceptionally能感知异常,并通过return修改返回数据
      return 10;
    });

    System.out.println("异步方法的返回值是:"+integerCompletableFuture.get()); //异步方法的返回值是:5
    System.out.println("main...end...");*/
//main...start...
//当前线程id: 20
//运行结果: 5
//异步任务成功完成了 ... 结果是: 5;异常是:null
//异步方法的返回值是:5
//main...end...

// 若出现异常, 则输出如下

//main...start...
//当前线程id: 20
//异步任务成功完成了 ... 结果是: null;异常是:java.util.concurrent.CompletionException: java.lang.ArithmeticException: / by zero
//异步方法的返回值是:10
//main...end...



    /** handle
     * 相较于whenComplete,它既能感知res和err,又能改变最终结果*/
   /* CompletableFuture<Integer> integerCompletableFuture = CompletableFuture.supplyAsync(() -> {
      System.out.println("当前线程id: " + Thread.currentThread().getId());
      //int i = 10 / 2;
      int i = 10 / 0;
      System.out.println("运行结果: " + i);
      return i;
    }, executor).handle((res,err)->{
      if (res != null) {
        return res * 2;
      }
      if (err != null) {
        return 0;
      }
      return 0;
    });

    System.out.println("异步方法的返回值是:"+integerCompletableFuture.get()); //异步方法的返回值是:5
    System.out.println("main...end...");*/
//main...start...
//当前线程id: 20
//异步方法的返回值是:0
//main...end...
  }
}
